package Example6;

/**
 * 基于双检测机制的懒汉式单例模式
 * 之前的分析：普通的单例模式线程不安全，并发时可能会创建多个实例。
 * 现在采用双检测机制来解决这个问题。
 * 优点：懒汉式，用到时才创建，可以解决资源占用浪费的问题。
 * 这种机制的缺点: 需要使用volatile关键字保证变量能够被多个线程正确处理。这个关键字会导致效率降低。
 */
public class DoubleCheckSingleton {
    //这里需要采用volatile关键字、
    private static volatile DoubleCheckSingleton doubleCheckSingleton=null;

    private DoubleCheckSingleton(){

    }

    public static DoubleCheckSingleton getInstance(){
        //问题一：
        //这里为什么要双检测，因为有可能多个线程通过第一个if，不加锁还是不能解决出现多例的问题，
        //加了锁之后为什么还要判断？因为多个线程通过第一个if，遇到锁，等待，如果没有第二个if，这多个线程都会创建实例，就又变成多个了。
        //问题二：锁加在第一个if外面不行吗？
        //低级错误，绝对不行。你让所有的调用这个方法的线程进来啥也不干先等着？线程多了岂不是超级慢。
        //先判断是不是已经有实例了，有的话，就直接返回，这不是快一点了。没有的话，再排队等着去申请。
        if(doubleCheckSingleton == null){
            synchronized (DoubleCheckSingleton.class){
                if(doubleCheckSingleton == null)
                    doubleCheckSingleton=new DoubleCheckSingleton();
            }
        }
        return doubleCheckSingleton;
    }
}
